【動画あり】早速YOLOv8を使って自作データセットで物体検出してみた
はじめに
こんちには。
データアナリティクス事業本部 機械学習チームの中村です。
YOLOv8がUltralyticsからリリースされたようです!!!???(以下ブログの日付では2023年1月8日)
Ultralyticsは、広く使われている物体検知のリポジトリのYOLOv5の開発元です。
YOLOv8にも期待が高まりますね!!
リポジトリは以下のようです。
論文はリポジトリ上で以下のようにTODOとなっており存在しないようですので、続報を待ちたいと思います。
本記事では以前YOLOv7のときに使用したオレンジアメのデータセットで、
物体検出をチューニングし動かしてみたいと思います。
データセットや以前のYOLOv7の詳細は以下の記事もご覧ください。
動作環境
今回はGoogle Colaboratory環境で実行しました。
ハードウェア情報は以下の通りです。
- GPU : Tesla T4, メモリ15GB
- メモリ : 13GB
主なソフトウェア・ライブラリのバージョンは以下となります。
- Python : 3.8.16
- CUDA : 11.2
- PyTorch : 1.13.0+cu116
環境の構築と確認
以下2種類の構築方法があるようです。
- pipのみでインストール方法
- リポジトリをクローンしてpipで構築する方法
今回はWarning等で結果が見えにくかったため、リポジトリからクローンする方法を選択しました。
正式には、pipのみで構築する方が良さそうなので、今後のアップデートを待ちます。
# Warningがでるため今回は不使用 # !pip install ultralytics # Git clone method (for development) !git clone https://github.com/ultralytics/ultralytics %pip install -qe ultralytics
記録としてclone時のコミットを以下に残しておきます。
Commit: 2bc36d97ce7f0bdc0018a783ba56d3de7f0c0518 Parents: 12c87ac00c31f0682a3ff96cb3a08570ea4a58bf Author: Glenn Jocher <[email protected]> Committer: Glenn Jocher <[email protected]> Date: Fri Jan 13 2023 02:07:33 GMT+0900 (日本標準時) Created using Colaboratory
インストール後はyolo
というコマンドが実行可能となります。
試しにサンプルのpredictを動かしてみます。
!yolo task=detect mode=predict model=yolov8n.pt \ source="https://ultralytics.com/images/bus.jpg"
以下のように結果が出力されました。
Downloading https://ultralytics.com/images/bus.jpg to bus.jpg... 100% 476k/476k [00:00<00:00, 108MB/s] Ultralytics YOLOv8.0.5 ? Python-3.8.16 torch-1.13.0+cu116 CUDA:0 (Tesla T4, 15110MiB) Downloading https://github.com/ultralytics/assets/releases/download/v0.0.0/yolov8n.pt to yolov8n.pt... 100% 6.24M/6.24M [00:00<00:00, 282MB/s] Fusing layers... YOLOv8n summary: 168 layers, 3151904 parameters, 0 gradients, 8.7 GFLOPs image 1/1 /content/bus.jpg: 640x480 4 persons, 1 bus, 1 stop sign, 14.0ms Speed: 0.5ms pre-process, 14.0ms inference, 36.7ms postprocess per image at shape (1, 3, 640, 640) Results saved to runs/detect/predict
1画像あたり14.0msで推論できています。ちなみにCPUの場合は288.3msでした。
推論結果の画像を出力してみます。
from IPython.display import Image Image("runs/detect/predict/bus.jpg")
環境構築は無事にできていそうです。
データセットの準備
こちらは以下の記事で準備したデータセットを使います。
データは以下のパスに配置したとします。
./dataset/candy/train ./dataset/candy/valid ./data.yaml
データセットの内容を表すdata.yaml
も前回同様以下のように記述します。
# train and val data as 1) directory: path/images/, 2) file: path/images.txt, or 3) list: [path1/images/, path2/images/] train: ./dataset/candy/train val: ./dataset/candy/valid # number of classes nc: 2 # class names names: ['melon-soda', 'orange']
ちなみにdata.yaml
の拡張子をyml
にすると、ネットワーク経由でデータセットの取得に行ってしまうため注意が必要です。
学習の実行
以下で実行できます。3000エポックで回してみました。
# Train YOLOv8n on COCO128 for 3 epochs !yolo task=detect mode=train model=yolov8n.pt data=data.yaml epochs=300 imgsz=640
ログは以下のように出力されました。
Ultralytics YOLOv8.0.5 ? Python-3.8.16 torch-1.13.0+cu116 CUDA:0 (Tesla T4, 15110MiB) yolo/engine/trainer: task=detect, mode=train, model=yolov8n.pt, data=data.yaml, epochs=300, patience=50, batch=16, imgsz=640, save=True, cache=False, device=, workers=8, project=None, name=None, exist_ok=False, pretrained=False, optimizer=SGD, verbose=False, seed=0, deterministic=True, single_cls=False, image_weights=False, rect=False, cos_lr=False, close_mosaic=10, resume=False, overlap_mask=True, mask_ratio=4, dropout=0.0, val=True, save_json=False, save_hybrid=False, conf=None, iou=0.7, max_det=300, half=False, dnn=False, plots=True, source=None, show=False, save_txt=False, save_conf=False, save_crop=False, hide_labels=False, hide_conf=False, vid_stride=1, line_thickness=3, visualize=False, augment=False, agnostic_nms=False, retina_masks=False, format=torchscript, keras=False, optimize=False, int8=False, dynamic=False, simplify=False, opset=17, workspace=4, nms=False, lr0=0.01, lrf=0.01, momentum=0.937, weight_decay=0.0005, warmup_epochs=3.0, warmup_momentum=0.8, warmup_bias_lr=0.1, box=7.5, cls=0.5, dfl=1.5, fl_gamma=0.0, label_smoothing=0.0, nbs=64, hsv_h=0.015, hsv_s=0.7, hsv_v=0.4, degrees=0.0, translate=0.1, scale=0.5, shear=0.0, perspective=0.0, flipud=0.0, fliplr=0.5, mosaic=1.0, mixup=0.0, copy_paste=0.0, cfg=None, hydra={'output_subdir': None, 'run': {'dir': '.'}}, v5loader=False, save_dir=runs/detect/train Downloading https://ultralytics.com/assets/Arial.ttf to /root/.config/Ultralytics/Arial.ttf... 100% 755k/755k [00:00<00:00, 75.0MB/s] Overriding model.yaml nc=80 with nc=2 from n params module arguments 0 -1 1 464 ultralytics.nn.modules.Conv [3, 16, 3, 2] 1 -1 1 4672 ultralytics.nn.modules.Conv [16, 32, 3, 2] 2 -1 1 7360 ultralytics.nn.modules.C2f [32, 32, 1, True] 3 -1 1 18560 ultralytics.nn.modules.Conv [32, 64, 3, 2] 4 -1 2 49664 ultralytics.nn.modules.C2f [64, 64, 2, True] 5 -1 1 73984 ultralytics.nn.modules.Conv [64, 128, 3, 2] 6 -1 2 197632 ultralytics.nn.modules.C2f [128, 128, 2, True] 7 -1 1 295424 ultralytics.nn.modules.Conv [128, 256, 3, 2] 8 -1 1 460288 ultralytics.nn.modules.C2f [256, 256, 1, True] 9 -1 1 164608 ultralytics.nn.modules.SPPF [256, 256, 5] 10 -1 1 0 torch.nn.modules.upsampling.Upsample [None, 2, 'nearest'] 11 [-1, 6] 1 0 ultralytics.nn.modules.Concat [1] 12 -1 1 148224 ultralytics.nn.modules.C2f [384, 128, 1] 13 -1 1 0 torch.nn.modules.upsampling.Upsample [None, 2, 'nearest'] 14 [-1, 4] 1 0 ultralytics.nn.modules.Concat [1] 15 -1 1 37248 ultralytics.nn.modules.C2f [192, 64, 1] 16 -1 1 36992 ultralytics.nn.modules.Conv [64, 64, 3, 2] 17 [-1, 12] 1 0 ultralytics.nn.modules.Concat [1] 18 -1 1 123648 ultralytics.nn.modules.C2f [192, 128, 1] 19 -1 1 147712 ultralytics.nn.modules.Conv [128, 128, 3, 2] 20 [-1, 9] 1 0 ultralytics.nn.modules.Concat [1] 21 -1 1 493056 ultralytics.nn.modules.C2f [384, 256, 1] 22 [15, 18, 21] 1 751702 ultralytics.nn.modules.Detect [2, [64, 128, 256]] Model summary: 225 layers, 3011238 parameters, 3011222 gradients, 8.2 GFLOPs Transferred 319/355 items from pretrained weights optimizer: SGD(lr=0.01) with parameter groups 57 weight(decay=0.0), 64 weight(decay=0.0005), 63 bias train: Scanning /content/dataset/candy/train/labels... 12 images, 0 backgrounds, 0 corrupt: 100% 12/12 [00:00<00:00, 416.79it/s] train: New cache created: /content/dataset/candy/train/labels.cache albumentations: Blur(p=0.01, blur_limit=(3, 7)), MedianBlur(p=0.01, blur_limit=(3, 7)), ToGray(p=0.01), CLAHE(p=0.01, clip_limit=(1, 4.0), tile_grid_size=(8, 8)) val: Scanning /content/dataset/candy/valid/labels... 6 images, 0 backgrounds, 0 corrupt: 100% 6/6 [00:00<00:00, 361.86it/s] val: New cache created: /content/dataset/candy/valid/labels.cache Image sizes 640 train, 640 val Using 2 dataloader workers Logging results to runs/detect/train Starting training for 300 epochs... Epoch GPU_mem box_loss cls_loss dfl_loss Instances Size 1/300 2.17G 1.256 3.881 1.284 209 640: 100% 1/1 [00:03<00:00, 3.78s/it] Class Images Instances Box(P R mAP50 mAP50-95): 100% 1/1 [00:01<00:00, 1.58s/it] all 6 33 0.00296 0.103 0.00223 0.00132 Epoch GPU_mem box_loss cls_loss dfl_loss Instances Size 2/300 2.61G 1.507 3.909 1.395 275 640: 100% 1/1 [00:01<00:00, 1.17s/it] Class Images Instances Box(P R mAP50 mAP50-95): 100% 1/1 [00:00<00:00, 2.20it/s] all 6 33 0.00254 0.0862 0.0022 0.00155 ... (中略) ... Epoch GPU_mem box_loss cls_loss dfl_loss Instances Size 300/300 8.5G 0.5368 0.5396 0.8365 178 640: 100% 1/1 [00:00<00:00, 1.45it/s] Class Images Instances Box(P R mAP50 mAP50-95): 100% 1/1 [00:00<00:00, 2.29it/s] all 6 33 0.991 0.983 0.993 0.896 300 epochs completed in 0.164 hours. Optimizer stripped from runs/detect/train/weights/last.pt, 6.3MB Optimizer stripped from runs/detect/train/weights/best.pt, 6.3MB Validating runs/detect/train/weights/best.pt... Ultralytics YOLOv8.0.5 ? Python-3.8.16 torch-1.13.0+cu116 CUDA:0 (Tesla T4, 15110MiB) Fusing layers... Model summary: 168 layers, 3006038 parameters, 0 gradients, 8.1 GFLOPs Class Images Instances Box(P R mAP50 mAP50-95): 100% 1/1 [00:00<00:00, 2.37it/s] all 6 33 0.999 0.98 0.993 0.9 melon-soda 6 4 1 0.995 0.995 0.933 orange 6 29 0.999 0.966 0.991 0.867 Speed: 0.3ms pre-process, 3.7ms inference, 0.0ms loss, 4.4ms post-process per image Saving runs/detect/train/predictions.json... Results saved to runs/detect/train
結果は以下に格納されます。
!ls -l runs/detect/train/weights/best.pt
-rw-r--r-- 1 root root 6258168 Jan 13 07:37 runs/detect/train/weights/best.pt
テスト動画による動作確認
以下に動画ファイルを格納します。
./dataset/candy/test
そして推論を以下で実行します。
!yolo task=detect mode=predict model=runs/detect/train/weights/best.pt conf=0.25 \ source="dataset/candy/test"
Ultralytics YOLOv8.0.5 ? Python-3.8.16 torch-1.13.0+cu116 CUDA:0 (Tesla T4, 15110MiB) Fusing layers... Model summary: 168 layers, 3006038 parameters, 0 gradients, 8.1 GFLOPs video 1/1 (1/619) /content/dataset/candy/test/2022-07-09_09-54-05.mp4: 384x640 12.6ms video 1/1 (2/619) /content/dataset/candy/test/2022-07-09_09-54-05.mp4: 384x640 1 orange, 7.9ms ... (中略) ... video 1/1 (618/619) /content/dataset/candy/test/2022-07-09_09-54-05.mp4: 384x640 2 melon-sodas, 11 oranges, 8.6ms video 1/1 (619/619) /content/dataset/candy/test/2022-07-09_09-54-05.mp4: 384x640 2 melon-sodas, 10 oranges, 12.1ms Speed: 0.4ms pre-process, 8.6ms inference, 1.2ms postprocess per image at shape (1, 3, 640, 640) Results saved to runs/detect/predict4
30fpsで約20秒の動画だったので、600枚程度の画像が処理されています。
以下がその結果の動画になります。
まとめ
いかがでしたでしょうか。
まだリリースされたばかりなので、とりあえずカスタムデータセットを1トライ学習するところだけをやってみました。
今までのYOLOv5やYOLOv7などと使用感は同じ感じで使えそうですね。
今後は比較検証やチューニング、YOLOv8の具体的な変更点などにもフォーカスした記事を出せたらと思います。
いますぐYOLOv8を試してみたいという方の参考になれば幸いです。